﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using PS.Engine;
using System.IO;
using PS.Engine.DataTypes;

namespace PS.Client
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private bool running;
        private PedestrianSimulation simulation;
        private SimulationInfo lastSimulationInformation;

        public MainWindow()
        {
            InitializeComponent();
            Pause.IsEnabled = false;
        }

        void simulation_SimulationChanged(object sender, SimulationEventArgs e)
        {
            // Misc
            TimeElapsed.Content = e.SimulationInfo.TimeElapsed > 0 ? e.SimulationInfo.TimeElapsed.ToString("#0.00") : "-";
            PedestrianCount.Content = e.SimulationInfo.PedestrianCount.ToString();
            PedestrianHomeCount.Content = e.SimulationInfo.PedestrianHomeCount.ToString();

            // Time
            PedestriansMinTime.Content = e.SimulationInfo.PedestriansMinTime > 0 ? e.SimulationInfo.PedestriansMinTime.ToString("#0.00") : "-";
            PedestriansMaxTime.Content = e.SimulationInfo.PedestriansMaxTime > 0 ? e.SimulationInfo.PedestriansMaxTime.ToString("#0.00") : "-";
            PedestriansAvgTime.Content = e.SimulationInfo.PedestriansAvgTime > 0 ? e.SimulationInfo.PedestriansAvgTime.ToString("#0.00") : "-";

            // Distance
            PedestriansMinDist.Content = e.SimulationInfo.PedestriansMinDistance > 0 ? e.SimulationInfo.PedestriansMinDistance.ToString("#0.00") : "-";
            PedestriansMaxDist.Content = e.SimulationInfo.PedestriansMaxDistance > 0 ? e.SimulationInfo.PedestriansMaxDistance.ToString("#0.00") : "-";
            PedestriansAvgDist.Content = e.SimulationInfo.PedestriansAvgDistance > 0 ? e.SimulationInfo.PedestriansAvgDistance.ToString("#0.00") : "-";

            // Initial Distance
            PedestriansMinInitialDist.Content = e.SimulationInfo.PedestriansMinInitialDistance > 0 ? e.SimulationInfo.PedestriansMinInitialDistance.ToString("#0.00") : "-";
            PedestriansMaxInitialDist.Content = e.SimulationInfo.PedestriansMaxInitialDistance > 0 ? e.SimulationInfo.PedestriansMaxInitialDistance.ToString("#0.00") : "-";
            PedestriansAvgInitialDist.Content = e.SimulationInfo.PedestriansAvgInitialDistance > 0 ? e.SimulationInfo.PedestriansAvgInitialDistance.ToString("#0.00") : "-";

            // Speed
            MinSpeed.Content = e.SimulationInfo.MinSpeed > 0 ? e.SimulationInfo.MinSpeed.ToString("#0.00") : "-";
            MaxSpeed.Content = e.SimulationInfo.MaxSpeed > 0 ? e.SimulationInfo.MaxSpeed.ToString("#0.00") : "-";
            BoorGentlemanTime.Content = e.SimulationInfo.BoorBusinessmanTime > 0 ? e.SimulationInfo.BoorBusinessmanTime.ToString("#0.00") : "-";
            GentlemanLikeGrandmaTime.Content = e.SimulationInfo.GentlemanLikeGrandmaTime > 0 ? e.SimulationInfo.GentlemanLikeGrandmaTime.ToString("#0.00") : "-";

            // check if simulation has ended
            if (!e.SimulationInfo.SimulationRunning)
            {
                simulation.Pause();
                Pause.IsEnabled = false;
                ExportStats.IsEnabled = true;
                lastSimulationInformation = e.SimulationInfo;
            }
        }

        private void ToggleRun_Click(object sender, RoutedEventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(environmentXmlPath.Text))
            {
                simulation = new PedestrianSimulation(environmentXmlPath.Text, (bool)DisplayWaypoints.IsChecked);
            }
            else
            {
                simulation = new PedestrianSimulation((bool)DisplayWaypoints.IsChecked);
            }
            simulation.SimulationChanged += new PedestrianSimulation.SimulationEventHandler(simulation_SimulationChanged);
            running = true;
            Pause.IsEnabled = true;
            DisplayWaypoints.IsEnabled = false;
            ToggleRun.IsEnabled = false;
            simulation.Run();
            running = false;
            ToggleRun.IsEnabled = true;
        }

        private void SimulationTerminated()
        {
            ToggleRun.Content = "Start";
        }

        private void TogglePause_Click(object sender, RoutedEventArgs e)
        {
            if (running)
            {
                running = false;
                Pause.Content = "Unpause";
                simulation.Pause();
            }
            else
            {
                Pause.Content = "Pause";
                running = true;
                simulation.Unpause();
            }
        }

        private void browsePath_Click(object sender, RoutedEventArgs e)
        {
            // Create OpenFileDialog
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();

            // Set filter for file extension and default file extension 
            dlg.DefaultExt = ".xml";
            dlg.Filter = "XML files (.xml)|*.xml";

            // Display OpenFileDialog by calling ShowDialog method 
            Nullable<bool> result = dlg.ShowDialog();

            // Get the selected file name and display in a TextBox 
            if (result == true)
            {
                // Open document
                string filename = dlg.FileName;
                environmentXmlPath.Text = filename;
            }
        }

        private void ExportStats_Click(object sender, RoutedEventArgs e)
        {
            // get export file path
            string exportFilePath = "simulation_information.csv";
            string environmentXml = "[default configuration]";
            if (!string.IsNullOrWhiteSpace(environmentXmlPath.Text))
            {
                // set environment Xml
                environmentXml = environmentXmlPath.Text;

                // get export file path from XML
                exportFilePath = System.IO.Path.ChangeExtension(environmentXml, ".csv");
            }
            StringBuilder statBuilder = new StringBuilder(1024);
            if (lastSimulationInformation != null)
            {
                statBuilder.Append(string.Format("Environment XML;{0}\n", environmentXml));
                statBuilder.Append(string.Format("Time Elapsed;{0}\n", lastSimulationInformation.TimeElapsed));
                statBuilder.Append(string.Format("Pedestrian Count;{0}\n", lastSimulationInformation.PedestrianHomeCount));
                statBuilder.Append(string.Format("Pedestrian Home Count;{0}\n", lastSimulationInformation.PedestrianHomeCount));
                statBuilder.Append(string.Format("Pedestrians Min Time;{0}\n", lastSimulationInformation.PedestriansMinTime));
                statBuilder.Append(string.Format("Pedestrians Max Time;{0}\n", lastSimulationInformation.PedestriansMaxTime));
                statBuilder.Append(string.Format("Pedestrians Avg Time;{0}\n", lastSimulationInformation.PedestriansAvgTime));
                statBuilder.Append(string.Format("Pedestrians Min Distance;{0}\n", lastSimulationInformation.PedestriansMinDistance));
                statBuilder.Append(string.Format("Pedestrians Max Distance;{0}\n", lastSimulationInformation.PedestriansMaxDistance));
                statBuilder.Append(string.Format("Pedestrians Avg Distance;{0}\n", lastSimulationInformation.PedestriansAvgDistance));
                statBuilder.Append(string.Format("Pedestrians Min Initial Distance;{0}\n", lastSimulationInformation.PedestriansMinInitialDistance));
                statBuilder.Append(string.Format("Pedestrians Max Initial Distance;{0}\n", lastSimulationInformation.PedestriansMaxInitialDistance));
                statBuilder.Append(string.Format("Pedestrians Avg Initial Distance;{0}\n", lastSimulationInformation.PedestriansAvgInitialDistance));
                statBuilder.Append(string.Format("Min Speed;{0}\n", lastSimulationInformation.MinSpeed));
                statBuilder.Append(string.Format("Max Speed;{0}\n", lastSimulationInformation.MaxSpeed));
                statBuilder.Append(string.Format("Boor Businessman Time;{0}\n", lastSimulationInformation.BoorBusinessmanTime));
                statBuilder.Append(string.Format("Gentleman Like Grandma Time;{0}\n", lastSimulationInformation.GentlemanLikeGrandmaTime));
            }
            else
            {
                statBuilder.Append("FEHLER BEIM ERSTELLEN DER AUSWERTUNG. SIMULATION INFORMATION NICHT GESETZT");
            }

            using (StreamWriter writer = new StreamWriter(exportFilePath))
            {
                writer.Write(statBuilder.ToString());
            }

            ExportStats.IsEnabled = false;
        }
    }
}
